package com.softer.chengxin.login.service.impl;

import com.softer.chengxin.blacklist.dao.BlacklistDao;
import com.softer.chengxin.common.config.CourseException;
import com.softer.chengxin.common.domin.Common;
import com.softer.chengxin.common.domin.CommonResult;
import com.softer.chengxin.common.enums.NumberEnum;
import com.softer.chengxin.common.enums.ResultEnum;
import com.softer.chengxin.common.util.DateFormatUtil;
import com.softer.chengxin.common.util.MD5;
import com.softer.chengxin.corp.domin.Corp;
import com.softer.chengxin.dongle.dao.DongleDao;
import com.softer.chengxin.login.dao.LoginDao;
import com.softer.chengxin.login.service.LoginService;
import com.softer.chengxin.score.dao.SDManagerDao;
import com.softer.chengxin.score.entity.ScoreComposite;
import com.softer.chengxin.score.entity.ScoreRecord;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @author Gong Zhiyang
 * @date 2018/9/26
 */
@Service
public class LoginServiceimpl implements LoginService {
    public static final String PW_PATTERN = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(.{8,20})$";
    private Logger logger = LoggerFactory.getLogger(LoginServiceimpl.class);
    private final BigDecimal ZERO = new BigDecimal(0);
    @Autowired
    private LoginDao dao;
    @Autowired
    private DongleDao dongleDao;
    @Autowired
    private BlacklistDao blacklistDao;
    @Autowired
    private SDManagerDao managerDao;
    /**
     * 登陆
     *
     * @param UserName  用户名
     * @param pwd       密码
     * @param LoginType 登陆类型（1物业企业，0主管部门,2街道/居委会）
     * @param KeyDog    加密狗
     * @return 登陆结果
     */
    @Override
    public CommonResult getUserByUserNameAndPassword(String UserName, String pwd, String LoginType, String KeyDog, HttpSession session) {

        if (StringUtils.isEmpty(LoginType)) {
            return new CommonResult(ResultEnum.FAIL.getCode(), "登录类型选择为空！");
        }
        if (StringUtils.isEmpty(UserName) || StringUtils.isEmpty(pwd)) {
            return new CommonResult(ResultEnum.FAIL.getCode(), "用户名或密码为空，登录失败！");
        }
        String PassWord = MD5.EncoderByMd5(pwd);
        Map<String, Object> users = new HashMap<>(16);
        Map<String, Object> map = new HashMap<>(16);
        map.put("username", UserName);
        map.put("password", PassWord);
        if (Common.ZERO.equals(LoginType) || String.valueOf(NumberEnum.TWO.getNum()).equals(LoginType)) {
            //LoginType  0主管  1企业  2街道/居委会
            String roleId = null;
            switch (LoginType) {
                //1admin  3区 2市 5协会 4街道 24社区
                case "0":
                    roleId = "1,2,3,5";
                    break;
                case "2":
                    roleId = "4,24";
                    LoginType = "0";
                    break;
            }
            map.put("roleId", roleId);
            //管理部门登陆
            //传递map参数 这里写入map
            //调用查询数据库
            users = dao.getUserByUserNameAndPassword(map);
            if (users == null || users.size() <= 0) {
                return new CommonResult(ResultEnum.FAIL.getCode(), "用户名密码错误！");
            }
        } else if (Common.ONE.equals(LoginType)) {
            //物业企业登陆
            //传递map参数 这里写入map
            //调用查询数据库
            //如有加密狗，验证是否绑定projectId(是的话，存放到session)
//            if (StringUtils.isEmpty(KeyDog)) {
//                return new CommonResult(ResultEnum.FAIL.getCode(), "请插入加密设备或下载驱动后重新登陆");
//            }
            users = dao.loginCorp(map);
            if (users == null || users.size() <= 0) {
                return new CommonResult(ResultEnum.FAIL.getCode(), "用户名密码错误！");
            }
            //查询企业是否在严重失信中
            int num = blacklistDao.findCorpInfo((int) users.get("id"));
            if (num > Integer.parseInt(Common.ZERO)) {
                return new CommonResult(ResultEnum.BROKEN_PROMISES.getCode(), "您所登陆的企业已在严重失信中");
            }
            //查询企业下绑定的机密狗集合
            List<String> dogList = dongleDao.getKeyDogList(String.valueOf(users.get("id")));
            if (dogList == null) {
                return new CommonResult(ResultEnum.FAIL.getCode(), "系统异常，请稍后重试");
            }
            if (StringUtils.isNotBlank(KeyDog)) {
                //如果插入了加密狗，则验证加密狗，否则按照企业登陆，拥有企业权限
                if (dogList.size() > 0) {
                    if (!dogList.contains(KeyDog)) {
                        return new CommonResult(ResultEnum.FAIL.getCode(), "该设备未绑定");
                    }
                    //检测加密狗
                    Map checkKeyDog = dongleDao.checkKeyDog(KeyDog);
                    //检测加密狗绑定的项目，如果项目为空，则为绑定的企业自有
                    String projectId = String.valueOf(checkKeyDog.get("project_id"));
                    if (StringUtils.isNotBlank(projectId)) {
                        session.setAttribute(Common.PROJECT_ID, projectId);
                    } else {
                        if (users != null) {
                            //将企业改为在线状态
                            dao.updateCompanyOnline(UserName, Common.ONE);
                        }
                    }
                }
            } else {
                //未插入加密狗，判断是否绑定过
                if (dogList.size() > 0) {
                    return new CommonResult(ResultEnum.DONGLE_FAIL.getCode(), "请插入加密设备");
                }
            }
        }
        //如果查询出来了，list肯定大于0
        users.put(Common.LOGIN_NAME, UserName);
        users.put("pwd", pwd);
        users.put("LoginType", LoginType);
        return getResult(users, session);
    }

    /**
     * 注册
     *
     * @param corp 注册信息
     * @return 注册结果
     */
    @Override
    public synchronized CommonResult addCorp(Corp corp) {
        if (StringUtils.isEmpty(corp.getBusinessLicenseNo()) ||
                StringUtils.isEmpty(corp.getRegisterType()) ||
                StringUtils.isEmpty(corp.getName()) ||
                StringUtils.isEmpty(corp.getPhone())) {
            return new CommonResult(Common.MINUS_ONE, "企业注册失败，请稍后再试,参数缺少！");
        }
        //检测统一社会信用代码企业工商营业执照号
        String no = dao.checkBusinessNo(corp.getBusinessLicenseNo());
        if (StringUtils.isNotBlank(no)) {
            return new CommonResult(Common.MINUS_ONE, "该营业执照号已经注册过");
        }
        //检测企业名
        String name = dao.checkQyName(corp.getName());
        if (StringUtils.isNotBlank(name)) {
            return new CommonResult(Common.MINUS_ONE, "该企业名已经被注册过");
        }
        String sqnoId;
        //生成随机密码
//        String pwd = generatePassword(8);
        try {
            //查询sqno中最大的id  进行加1生成这次要插入的id
            sqnoId = dao.getMaxOrderNo();
            Map<String, Object> sqNoMap = new HashMap<>();
            if (sqnoId == null) {
                //没有最大id ，生成第一个id 并且存储
                sqnoId = Common.INIT_SQ_NO;
            } else {
                sqnoId = Common.ZERO + String.valueOf(Integer.parseInt(sqnoId) + Integer.parseInt(Common.ONE));
            }
            sqNoMap.put("sq_type", corp.getRegisterType());
            sqNoMap.put("order_no", sqnoId);
            dao.addSqnoinfo(sqNoMap);
            //添加企业信息
            //md5加密
            String userName = String.valueOf(sqnoId);
            String passWord = MD5.EncoderByMd5(corp.getPwd());
            corp.setQyNo(userName);
            corp.setPwd(passWord);
            Integer community = corp.getCommunity();
            if (community == null) {
                corp.setCommunity(Integer.parseInt(Common.ZERO));
            }
            int num = dao.addWycorpbaseinfo(corp);
            if (num > Integer.parseInt(Common.ZERO)) {
                //添加score_composite表一条记录,未分等级
                addScoreRecord(corp.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CourseException(Common.MINUS_ONE, "企业注册失败，请稍后再试, 系统错误！");
        }
        return new CommonResult(Integer.parseInt(Common.ONE), "企业注册成功，您的用户名为:" + sqnoId);
    }


    /**
     * 退出登陆
     *
     * @param session 缓存
     * @return 结果
     */
    @Override
    public CommonResult loginOut(HttpSession session) {
        if (session != null) {
            //登陆类型
            String loginType = (String) session.getAttribute(Common.LOGIN_TYPE);
            String loginName = (String) session.getAttribute(Common.LOGIN_NAME);
            if (Common.ONE.equals(loginType)) {
                //修改企业在线状态:不在线
                dao.updateCompanyOnline(loginName, Common.ZERO);
            }
            session.removeAttribute(Common.LOGIN_NAME);
            session.invalidate();
            logger.info("用户[{}]退出登录！", loginName);
        }
        return new CommonResult(ResultEnum.SUCCESS.getCode(), "退出成功！");
    }


    /**
     * 添加score_composite表一条记录，默认基础为0分，等级为-
     */
    private void addScoreRecord(Integer id) {
        ScoreComposite scoreComposite = new ScoreComposite();
        //获取主管部门定义的年份
        String year = DateFormatUtil.getSysYear();
        scoreComposite.setYear(year);
        scoreComposite.setLevel("-");
        scoreComposite.setBasicScore(BigDecimal.ZERO);
        scoreComposite.setExcellentScore(BigDecimal.ZERO);
        scoreComposite.setNegativeScore(BigDecimal.ZERO);
        scoreComposite.setAllScore(BigDecimal.ZERO);
        scoreComposite.setCompanyId(id);
        managerDao.insertScoreComposite(scoreComposite);
    }


    private CommonResult getResult(Map users, HttpSession session) {
        if (users != null && users.get("id") != null) {
            String name = String.valueOf(users.get("Username"));
            //返回正确
            if (session != null) {
                session.setAttribute(Common.LOGIN_NAME, String.valueOf(users.get(Common.LOGIN_NAME)));
                session.setAttribute(Common.ID, users.get("id"));
                session.setAttribute(Common.LOGIN_TYPE, String.valueOf(users.get("LoginType")));
            }
            //将企业改为在线状态
            dao.updateCompanyOnline(name, Common.ONE);
            logger.info("用户[{}]登录", name);
            if (String.valueOf(users.get("pwd")).matches(PW_PATTERN)) {
                return new CommonResult(ResultEnum.SUCCESS.getCode(), "登录成功！");
            } else {
                return new CommonResult(ResultEnum.WEAK_PWD.getCode(), "弱密码，请修改为至少八位的大小写字母加数字的组合");
            }
        }
        return new CommonResult(ResultEnum.FAIL.getCode(), "用户名密码错误，登录失败！");
    }

    /**
     * 校验是否在线
     *
     * @param loginName 登录名
     * @return 校验结果
     */
    public CommonResult checkLoginName(String loginName) {
        if (StringUtils.isBlank(loginName)) {
            return new CommonResult(ResultEnum.FAIL.getCode(), "请重新登陆后操作");
        }
        return CommonResult.response(NumberEnum.ONE.getNum());
    }
}

